package com.tff.gmall.search.Impl;

import com.alibaba.dubbo.config.annotation.Service;
import com.tff.gmall.beans.PmsSearchParam;
import com.tff.gmall.beans.PmsSearchSkuInfo;
import com.tff.gmall.service.SearchService;
import io.searchbox.client.JestClient;
import io.searchbox.core.Search;
import io.searchbox.core.SearchResult;
import org.apache.commons.lang3.StringUtils;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.index.query.MatchQueryBuilder;
import org.elasticsearch.index.query.TermQueryBuilder;
import org.elasticsearch.search.builder.SearchSourceBuilder;
import org.elasticsearch.search.highlight.HighlightBuilder;
import org.elasticsearch.search.sort.SortOrder;
import org.springframework.beans.factory.annotation.Autowired;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

/**
 * @author Fafa Tuo
 * @version 1.0
 * @date 2021/7/2 14:45
 */
@Service
public class SearchServiceImpl implements SearchService {

    @Autowired
    private JestClient jestClient;

    @Override
    public List<PmsSearchSkuInfo> list(PmsSearchParam pmsSearchParam) {

        String searchDsl = getSearch(pmsSearchParam);

        System.out.println(searchDsl);

        //存放查询返回的结果
        List<PmsSearchSkuInfo> searchSkuInfos = new ArrayList<>();

        Search search = new Search.Builder(searchDsl).addIndex("gmall0105pms").addType("PmsSkuInfo").build();
        SearchResult execute = null;
        try {
            execute = jestClient.execute(search);
        } catch (IOException e) {
            e.printStackTrace();
        }
        List<SearchResult.Hit<PmsSearchSkuInfo, Void>> hits = execute.getHits(PmsSearchSkuInfo.class);
        System.out.println("total="+execute.getTotal());
        for (SearchResult.Hit<PmsSearchSkuInfo,Void> hit: hits) {
            PmsSearchSkuInfo source = hit.source;
            //处理高亮
            Map<String, List<String>> highlight = hit.highlight;

            //解析高亮有前提，必须是关键字搜索才有高亮，其他没有。否则会报空指针异常
            if(highlight != null){
                String skuName = highlight.get("skuName").get(0);
                source.setSkuName(skuName);
            }
            searchSkuInfos.add(source);
        }

        return searchSkuInfos;
    }

    private String getSearch(PmsSearchParam pmsSearchParam) {
        String[] skuAttrValueList = pmsSearchParam.getValueId();
        String keyword = pmsSearchParam.getKeyword();
        String catalog3Id = pmsSearchParam.getCatalog3Id();

        //jest 的dsl工具
        SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();

        //bool
        BoolQueryBuilder boolQueryBuilder = new BoolQueryBuilder();

        //filter
        if(StringUtils.isNotBlank(catalog3Id)){
            TermQueryBuilder termQueryBuilder = new TermQueryBuilder("catalog3Id",catalog3Id);
            boolQueryBuilder.filter(termQueryBuilder);
        }
        if(skuAttrValueList != null){
            for (String pmsSkuAttrValue:skuAttrValueList) {
                TermQueryBuilder termQueryBuilder = new TermQueryBuilder("skuAttrValueList.valueId",pmsSkuAttrValue);
                boolQueryBuilder.filter(termQueryBuilder);
            }
        }
        //must
        if(StringUtils.isNotBlank(keyword)){
            MatchQueryBuilder matchQueryBuilder = new MatchQueryBuilder("skuName",keyword);
            boolQueryBuilder.must(matchQueryBuilder);
        }

        //query
        searchSourceBuilder.query(boolQueryBuilder);
        //from
        searchSourceBuilder.from(0);
        //size
        searchSourceBuilder.size(20);

        //highlighet
        HighlightBuilder highlightBuilder = new HighlightBuilder();
        //自定义高亮显示的样式
        highlightBuilder.preTags("<span style='color:red;'>");
        highlightBuilder.field("skuName");
        highlightBuilder.postTags("</span>");
        searchSourceBuilder.highlight(highlightBuilder);
        //sort
        searchSourceBuilder.sort("id", SortOrder.DESC);

        //聚合
        /*TermsBuilder group_attr = AggregationBuilders.terms("name").field("skuAttrValueList.valueId");
        searchSourceBuilder.aggregation(group_attr);*/

        return searchSourceBuilder.toString();
    }
}
